//#include "tsres.h"
#include "tsdna.h"
#include "tssynapse.h"
#include <stdlib.h>
#include <glib-object.h>

typedef struct _TsRes {
  GObject parent_instance;

  gint64 id;

  gint match;

  gboolean status;

  gchar *utf8;

  gunichar *ucs4;

  gpointer symlink;//symbolic link

  GObject *next;
} TsRes;
typedef struct _TsResClass {
    GObjectClass parent_class;
} TsResClass;
enum {
  PROP_0,
  PROP_ID,
  PROP_MATCH,
  PROP_STATUS,
  PROP_UTF8,
  PROP_UCS4,
  PROP_SYMLINK,
  PROP_NEXT,
  N_PROPERTIES };

static GParamSpec *properties[N_PROPERTIES] = { NULL, };

G_DEFINE_TYPE (TsRes, ts_res, G_TYPE_OBJECT)

static void
ts_res_set_id (TsRes *obj,
                     gint64        value)
{
  if (obj->id != value)
    {
      obj->id = value;

      g_assert (properties[PROP_ID] != NULL);
      g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_ID]);
    }
}
static void
ts_res_set_match (TsRes *obj,
                     gint        value)
{
  if (obj->match != value)
    {
      obj->match = value;
      g_assert (properties[PROP_MATCH] != NULL);
      g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_MATCH]);
    }
}
static void
ts_res_set_status (TsRes *obj,
                     gboolean    status)
{
  status = !!status;

  if (obj->status != status)
    {
      obj->status = status;

      g_assert (properties[PROP_STATUS] != NULL);
      g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_STATUS]);
    }
}

static void
ts_res_set_utf8 (TsRes  *obj,
                     const gchar *utf8)
{
  if (g_strcmp0 (obj->utf8, utf8) != 0)
    {
      g_free (obj->utf8);
      obj->utf8 = g_strdup (utf8);

      g_assert (properties[PROP_UTF8] != NULL);
      g_object_notify_by_pspec (G_OBJECT (obj), properties[PROP_UTF8]);
    }
}

static void
ts_res_set_ucs4 (TsRes  *obj,
                     gunichar *value)
{
  obj->ucs4 = value;
}
static void
ts_res_set_symlink (TsRes  *obj,
                     gpointer value)
{
  obj->symlink = value;
}
static void
ts_res_set_next (TsRes  *obj,
                     gpointer value)
{
  obj->next = (GObject *) value;
}

static void
ts_res_finalize (GObject *gobject)
{
  TsRes *self = (TsRes *) gobject;

  g_free (self->utf8);

  g_object_notify (gobject, "port");
  g_object_notify_by_pspec (gobject, properties[PROP_STATUS]);

  G_OBJECT_CLASS (ts_res_parent_class)->finalize (gobject);
}

static void
ts_res_set_property (GObject *gobject,
                          guint prop_id,
                          const GValue *value,
                          GParamSpec *pspec)
{
  TsRes *tobj = (TsRes *) gobject;

  g_assert_cmpint (prop_id, !=, 0);
  g_assert_cmpint (prop_id, !=, N_PROPERTIES);
  g_assert (pspec == properties[prop_id]);

  switch (prop_id)
    {
    case PROP_ID:
      ts_res_set_id (tobj, g_value_get_int64 (value));
      break;

    case PROP_MATCH:
      ts_res_set_match (tobj, g_value_get_int (value));
      break;

    case PROP_STATUS:
      ts_res_set_status (tobj, g_value_get_boolean (value));
      break;

    case PROP_UTF8:
      ts_res_set_utf8 (tobj, g_value_get_string (value));
      break;
    case PROP_UCS4:
      ts_res_set_ucs4 (tobj, g_value_get_pointer (value));
      break;
    case PROP_SYMLINK:
      ts_res_set_symlink (tobj, g_value_get_pointer (value));
      break;
    case PROP_NEXT:
      ts_res_set_next (tobj, g_value_get_object (value));
      break;

    default:
      g_assert_not_reached ();
    }
}

static void
ts_res_get_property (GObject *gobject,
                          guint prop_id,
                          GValue *value,
                          GParamSpec *pspec)
{
  TsRes *tobj = (TsRes *) gobject;

  g_assert_cmpint (prop_id, !=, 0);
  g_assert_cmpint (prop_id, !=, N_PROPERTIES);
  g_assert (pspec == properties[prop_id]);

  switch (prop_id)
    {
    case PROP_ID:
      g_value_set_int64 (value, tobj->id);
      break;

    case PROP_MATCH:
      g_value_set_int (value, tobj->match);
      break;

    case PROP_STATUS:
      g_value_set_boolean (value, tobj->status);
      break;

    case PROP_UTF8:
      g_value_set_string (value, tobj->utf8);
      break;

    case PROP_UCS4:
      g_value_set_pointer (value, tobj->ucs4);
      break;

    case PROP_SYMLINK:
      g_value_set_pointer (value, tobj->symlink);
      break;

    case PROP_NEXT:
      g_value_set_object (value, (gpointer) tobj->next);
      break;

    default:
      g_assert_not_reached ();
    }
}

static void
ts_res_class_init (TsResClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  properties[PROP_ID] = g_param_spec_int64 ("id", "id", "id",
      -1, G_MAXINT64, 0, G_PARAM_READWRITE);
  properties[PROP_MATCH] = g_param_spec_int ("match", "match", "match",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);

  properties[PROP_STATUS] = g_param_spec_int ("status", "Status", "Status",
      -1, G_MAXINT, 0, G_PARAM_READWRITE);
  properties[PROP_UTF8] = g_param_spec_string ("utf8", "Name", "Name",
      NULL, G_PARAM_READWRITE);
  properties[PROP_UCS4] = g_param_spec_pointer (
      "ucs4", "ucs4", "ucs4", G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_SYMLINK] = g_param_spec_pointer ("symlink", "symlink", "symlink",
      G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
  properties[PROP_NEXT] = g_param_spec_object ("next", "next", "next",
      G_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);

  gobject_class->set_property = ts_res_set_property;
  gobject_class->get_property = ts_res_get_property;
  gobject_class->finalize = ts_res_finalize;

  g_object_class_install_properties (gobject_class, N_PROPERTIES, properties);
}

static void
ts_res_init (TsRes *self)
{
}

TsRes *ts_res_new (gint64 id, gint match,
    gpointer utf8, gpointer ucs4, gpointer symlink)
{
  TsRes *res;
  res =  g_object_new (ts_res_get_type (), "match", match, "utf8", utf8,
      "ucs4", ucs4, "symlink", symlink, NULL);

  return res;
}
TsRes *ts_ress_get_object (TsRes *gobject,
                          const gchar *utf8,
                          gpointer value)
{
  TsRes *tobj = gobject;
  guint prop_id;
  gboolean found = FALSE;
  if (!g_strcmp0 (utf8, "id")) {
    prop_id = PROP_ID;
  }
  while (tobj) {
  //g_debug ("%s\tid:%d\n", __func__, tobj->id);
    switch (prop_id)
      {
      case PROP_ID:
        if (tobj->id == *(gint64 *)value) {
          found = TRUE;
        }
        break;
      default:
        g_assert_not_reached ();
      }
    if (found)
      break;
    tobj = (TsRes *) tobj->next;
  }
  return tobj;
}
